/*
   Copyright 2007 Carsten Saager (carsten@saager.org)

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

package org.saager.traits;

import java.lang.reflect.Proxy;

import org.saager.traits.Traits.Trait;

/**
 * Factory superclass to define traits from abstract classes.
 * <br></br><br></br>
 * A trait is often an abstract class as it declares interfaces without implementing them. 
 * This is an easy way of transforming a class into a trait. The preferred way is although
 * the use of {@link Trait}.
 * @author Carsten
 * @deprecated The class is on parole, if use-case can be found that require this mechanism the deprecation will be lifted
 */
public abstract class TraitableFactory {
    /**
     * Decorate the abstract class with the missing methods by delegation to the proxy
     * <br></br><br></br>
     * The method is called from {@link Traits#with(TraitableFactory)}
     * @param proxy 
     * @return trait with delegation to the newly created {@link Proxy} class 
     */
    protected abstract Object decorate(Object proxy);

    /**
     * The interfaces the {@link Proxy} will implement.
     * <br></br><br></br>
     * The concrete factory can override this method to define its own subset of the declared interfaces. 
     * @param trait
     * @return the declared interfaces to be used for the proxy construction
     */
    protected Class<?>[] interfaces(Class<?> trait) {
        return trait.getInterfaces();
    }
}